﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Library
{
    public static class Engine
    {
        public static GraphicsDevice GraphicsDevice;
        public static SpriteBatch SpriteBatch;
        public static ScreenCollection Screens = new ScreenCollection();
        public static GameTime GameTime;
        public static bool IsInitialized = false;
        public static IEServiceContainer Services;
        public static IEContentManager Content;

        public static Screen BgScreen;
        public static Screen DefScreen;


        public static void SetupEngine(IGraphicsDeviceService GraphicsDeviceService)
        {
            Engine.GraphicsDevice = GraphicsDeviceService.GraphicsDevice;
            Engine.SpriteBatch = new SpriteBatch(GraphicsDeviceService.GraphicsDevice);
            Engine.IsInitialized = true;
            Engine.Services = new IEServiceContainer();
            Engine.Services.AddService(typeof(IGraphicsDeviceService), GraphicsDeviceService);
            Engine.Content = new IEContentManager(Services);

            BgScreen = new Screen("Engine.BgScreen");
            BgScreen.OverridesStoppedDraw = true;
            BgScreen.OverridesStoppedInput = true;
            BgScreen.OverridesStoppedUpdate = true;

            DefScreen = BgScreen;
        }

        public static void Update(GameTime gameTime)
        {
            Engine.GameTime = gameTime;
            List<Screen> updating = new List<Screen>();

            foreach (Screen sc in Screens)
                updating.Add(sc);

            for (int i = Screens.Count - 1; i >= 0; i--)
                if (Screens[i].StopsUpdate)
                {
                    if (i > 0)
                        for (int j = i - 1; j >= 0; j--)
                            if (!Screens[j].OverridesStoppedUpdate)
                                updating.Remove(Screens[j]);
                    break;
                }
            foreach(Screen sc in updating)
                if (sc.Initialized)
                    sc.Update();

            updating.Clear();

            foreach (Screen sc in Screens)
                updating.Add(sc);

            for (int i = Screens.Count - 1; i >= 0; i--)
                if (Screens[i].StopsInput)
                {
                    if (i > 0)
                        for (int j = i - 1; j >= 0; j--)
                            if (!Screens[j].OverridesStoppedInput)
                                updating.Remove(Screens[j]);
                    break;
                }

            foreach (Screen sc in Screens)
                if (!sc.InputDisabled)
                    sc.IsInputAllowed = updating.Contains(sc);
                else
                    sc.IsInputAllowed = false;
        }


        public static void Draw(GameTime gameTime, ComponentType RenderType)
        {
            Engine.GameTime = gameTime;
            List<Screen> drawing = new List<Screen>();
            GraphicsDevice.Clear(Color.CornflowerBlue);
            foreach (Screen sc in Screens)
                if (sc.Visible)
                    drawing.Add(sc);
            for (int i = Screens.Count - 1; i >= 0; i--)
                if (Screens[i].StopsDraw)
                {
                    if (i > 0)
                        for (int j = i - 1; j >= 0; j--)
                        {
                            if (!Screens[j].OverridesStoppedDraw)
                                drawing.Remove(Screens[j]);
                        }
                    break;
                }
            foreach (Screen sc in drawing)
                if (sc.Initialized)
                    sc.Draw(RenderType);
        }

    }
}